const Resource = require("../models/resourceModel");
const Device = require("../models/deviceModel");
const catchAsync = require("./../utils/catchAsync");
const randomID = require("../utils/utils")
const Room = require("../models/roomModel");
const Campus = require("../models/campusModel");
const Building = require("../models/buildingModel");

const axios = require("axios");
const AppError = require("./../utils/appError");
const livingDevice = require("../livingDevice");
require("dotenv").config({ path: "../config.env" })

exports.getAllDevices = catchAsync(async (req, res, next) => {
  const query = Device.find()
    .populate({ path: "deviceCampus", select: "campus_name" })
    .populate({ path: "deviceBuilding", select: "building_name" })
    .populate({ path: "deviceRoom", select: "room_number" })
  let devices = await query;
  // 验证设备是否连接
  let requestData = { userName: "admin", password: "admin", md5Flag: 0 };
  let url = ""
  let data = {}
  for (let i = 0; i < devices.length; i++) {
    // mongoose.find后出的问题
    try {
      console.log("come");
      devices[i]["_doc"]["status"] = "未连接"
      url = "http://" + devices[i].deviceIP + "/sdk/LoginSystem";
      data = await axios.post(url, requestData, {
        timeout: 200
      });
      if (data.data.errMsg == "操作成功") {
        console.log("success");
        devices[i]["_doc"]["status"] = "已连接"
      }
    } catch (err) {
      console.log("err");
      devices[i]["_doc"]["status"] = "未连接"
    }
  }
  res.status(200).json({
    status: "success",
    data: {
      devices,
    },
  });
});

exports.createDevice = catchAsync(async (req, res, next) => {
  let deviceObject;
  let data;
  // 处理位置错误
  try {
    deviceObject = await new livingDevice({ deviceIp: req.body.deviceIP })
    data = await deviceObject.getDeviceMessage();
    req.body.deviceID = data.data.data.deviceId;
  } catch (err) {
    try {
      const newDevice = await Device.create(req.body);
    } catch (err) {
      if(err.keyPattern.deviceID){
        if(err.keyValue.deviceID == null){
          res.json({
            status: "fail",
            message: "设备ID重复"
          })
          return;
        }
      }
    }
    res.json({
      status: "fail",
      message: "设备未开机或输入ip有误导致ID未能成功获取，请点连接重新连接设备"
    })
    return;
  }
  const newDevice = await Device.create(req.body);
  res.status(201).json({
    status: "success",
    data: newDevice,
  });
});

// 验证连接且获取设备ID
exports.checkAndGetDeviceID = catchAsync(async (req, res, next) => {
  let deviceObject;
  let data;
  let updateOne = {};
  // 处理位置错误
  try {
    deviceObject = await new livingDevice({ deviceIp: req.body.deviceIP })
    data = await deviceObject.getDeviceMessage();
    console.log("🚀 ~ file: deviceController.js ~ line 94 ~ exports.checkAndGetDeviceID=catchAsync ~ data", data.data)
    updateOne.deviceID = data.data.data.deviceId;
    console.log("🚀 ~ file: deviceController.js ~ line 95 ~ exports.checkAndGetDeviceID=catchAsync ~ updateOne", updateOne)
  } catch (err) {
    res.json({
      status: "fail",
      message: "设备未开机或输入ip有误导致ID未能成功获取，请点连接重新连接设备"
    })
    return;
  }
  await Device.findByIdAndUpdate(req.body._id, updateOne)
  res.json({
    status: "success",
  })
})

exports.mutipleDevices = catchAsync(async (req, res, next) => {
  let BuildingList = await Building.find();
  let CampusList = await Campus.find();
  let RoomList = await Room.find();
  req.body.forEach(item => {
    BuildingList.forEach(building => {
      if (building.building_name == item.deviceBuilding) {
        item.deviceBuilding = building._id
      }
    })
    CampusList.forEach(campus => {
      if (campus.campus_name == item.deviceCampus) {
        item.deviceCampus = campus._id
      }
    })
    RoomList.forEach(room => {
      if (room.room_number == item.deviceRoom) {
        item.deviceRoom = room._id
      }
    })
  })
  // 添加数据库
  const result = await Device.insertMany(req.body);
  res.status(201).json({
    status: "success",
    result
  });
})

exports.getDevice = catchAsync(async (req, res, next) => {
  console.log("getClass 进来啦");

  const device = await Device.findById(req.params.id);

  if (!device) {
    return next(new AppError("该设备不存在", 404));
  }

  console.log(device);
  res.status(200).json({
    status: "success",
    data: {
      device,
    },
  });
});

exports.getDeviceFromRoomID = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  if (!device) {
    res.json({
      status: "fail",
      message: "该房间安没有设备"
    })
  }
  res.json({
    status: "success",
    device
  })
})

exports.updateDevice = catchAsync(async (req, res, next) => {
  const device = await Device.findByIdAndUpdate(req.params.id, req.body, {
    new: true,
    runValidators: true,
  });
  if (!device) {
    return next(new AppError("该班级不存在", 404));
  }
  res.status(200).json({
    status: "success",
    data: {
      device,
    },
  });
});

exports.deleteDevice = catchAsync(async (req, res, next) => {
  const device = await Device.findByIdAndDelete(req.params.id);
  if (!device) {
    return next(new AppError("该机构不存在", 404));
  }

  res.status(204).json({
    status: "success",
    data: null,
  });
});

//开始录制
exports.startRecord = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  if (!device) {
    res.json({
      status: "fail",
      message: "该教室暂无设备"
    })
  }
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice)
  // 检查是否存在上次得录播文件
  let checkFileStatus = await deviceObject.checkFile();
  if (!checkFileStatus.data.result) {
    res.json({
      status: "fail",
      message: "操作异常，请重试！"
    })
    return;
  }
  if (checkFileStatus.data.data.fileList.length) {
    res.json({
      status: "fail",
      message: "设备中还存有上次录播文件请保存后再重试"
    })
    return;
  }
  // 开始录制
  let data = await deviceObject.startRecord();
  if (!data.result) {
    res.json({
      status: "fail",
      message: data.errMsg,
    })
    return;
  }
  res.status(201).json({
    status: "success",
  });
});

// 暂停录制
exports.pauseRecord = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  if (!device) {
    res.json({
      status: "fail",
      message: "该教室暂无设备"
    })
  }
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice)
  // 暂停录制
  let data = await deviceObject.pauseRecord();
  if (!data.result) {
    res.json({
      status: "fail",
      message: data.errMsg,
    })
    return;
  }
  res.status(201).json({
    status: "success",
  });
});

//继续录制
exports.continueRecord = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  if (!device) {
    res.json({
      status: "fail",
      message: "该教室暂无设备"
    })
  }
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice)
  // 开始录制
  let data = await deviceObject.startRecord();
  if (!data.result) {
    res.json({
      status: "fail",
      message: data.errMsg,
    })
    return;
  }
  res.status(201).json({
    status: "success",
  });
});

// 结束录制
exports.endRecord = catchAsync(async (req, res, next) => {
  console.log("come-----------");
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  let room = await Room.findOne({
    _id: req.params.room_id
  })
  if (!room) {
    res.json({
      status: "fail",
      message: "教室id有误"
    })
    return;
  }
  let room_number = room.room_number;
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice)
  let data = await deviceObject.endRecord();
  // 上传
  const downloadUrl = await deviceObject.getDownLoadUrl();
  console.log("🚀 ~ file: deviceController.js ~ line 306 ~ exports.endRecord=catchAsync ~ downloadUrl", downloadUrl)
  if (downloadUrl == "") {
    res.json({
      status: "fail",
      message: "未找到录播文件,请检查是否开始录播"
    })
  }
  // 上传录播文件
  let formData = {
    fileId: randomID.idCreator(12, 16),
    orgId: req.body.oid,
    url: downloadUrl,
    device: newDevice,
    room_number,
  };
  const apiUrl = "http://" + process.env.serverHost + ":" + process.env.serverPort + "/dumpFile";
  try {
    const uploadResult = await axios.post(apiUrl, formData);
    if (!uploadResult) {
      res.json({
        status: "fail",
        message: "上传失败"
      })
    }
  } catch (err) {
    console.log(err);
    res.json({
      status: "fail",
      message: "文件服务出错!"
    })
  }
  //生成录播视频地址存在数据库
  let LookUrl =
    "http://" +
    process.env.serverHost +
    ":" + process.env.serverPort +
    "/static/" +
    req.body.oid +
    "/teacher/" +
    formData.fileId +
    ".mp4";
  let requestData = {
    name: `${req.body.teacherName}_${req.body.date}`,
    authorId: req.body.authorId,
    url: LookUrl,
    size: deviceObject.fileList[0].fileSize,
    lesson_id: req.body.lessonId,
    tags: [req.body.className, req.body.courseName],
    duration: 0,
    rsType: "mp4",
  };
  const newResource = await Resource.create(requestData);
  res.status(201).json({
    status: "success",
  });
});

// 开始直播
exports.startRTMP = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  let room = await Room.findOne({
    _id: req.params.room_id
  })
  if (!room) {
    res.json({
      status: "fail",
      message: "教室id有误"
    })
    return;
  }
  if (!device) {
    res.json({
      status: "fail",
      message: "该教室暂无设备"
    })
    return;
  }
  let room_number = room.room_number
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice, room_number)
  // 设置推流状态
  // let result = await deviceObject.SetRtmpConfig(1)
  await deviceObject.StartRtmp();
  res.status(201).json({
    status: "success",
    device
  });
})

// 停止直播
exports.stopRtmp = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice)
  await deviceObject.StopRtmp();
  res.status(201).json({
    status: "success",
  });
});

// 开始录播
exports.RtmpAddRecord = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  let room = await Room.findOne({
    _id: req.params.room_id
  })
  if (!room) {
    res.json({
      status: "fail",
      message: "教室id有误"
    })
    return;
  }
  if (!device) {
    res.json({
      status: "fail",
      message: "该教室暂无设备"
    })
    return;
  }
  let room_number = room.room_number
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice, room_number)
  // 检查是否存在上次得录播文件
  let checkFileStatus = await deviceObject.checkFile();
  if (!checkFileStatus.data.result) {
    res.json({
      status: "fail",
      message: "操作异常，请重试！"
    })
    return;
  }
  if (checkFileStatus.data.data.fileList.length) {
    res.json({
      status: "fail",
      message: "设备中还存有上次录播文件请保存后再重试"
    })
    return;
  }
  // 一键开启
  let { data } = await deviceObject.RtmpAddRecord(1);
  res.status(201).json({
    status: "success",
    device
  });
})

// 停止录播
exports.closeRtmpAddRecord = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  let room = await Room.findOne({
    _id: req.params.room_id
  })
  if (!device) {
    res.json({
      status: "fail",
      message: "该房间没有设备"
    })
  }
  let room_number = room.room_number
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice, room_number)
  data = await deviceObject.RtmpAddRecord(0);
  // 上传
  const downloadUrl = await deviceObject.getDownLoadUrl();
  if (downloadUrl == "") {
    res.json({
      status: "fail",
      message: "未找到录播文件,请检查是否开始录播"
    })
  }
  // 上传录播文件
  let formData = {
    fileId: randomID.idCreator(12, 16),
    orgId: req.body.oid,
    url: downloadUrl,
    device: newDevice,
    room_number,
  };
  const apiUrl = "http://" + process.env.serverHost + ":" + process.env.serverPort + "/dumpFile";
  console.log("🚀 ~ file: deviceController.js ~ line 132 ~ exports.endRecord=catchAsync ~ apiUrl", apiUrl)
  const uploadResult = await axios.post(apiUrl, formData);
  if (!uploadResult) {
    res.json({
      status: "fail",
      message: "上传失败"
    })
  }
  //生成录播视频地址存在数据库
  let LookUrl =
    "http://" +
    process.env.serverHost +
    ":" + process.env.serverPort +
    "/static/" +
    req.body.oid +
    "/teacher/" +
    formData.fileId +
    ".mp4";
  let requestData = {
    name: "录播文件",
    authorId: req.body.authorId,
    url: LookUrl,
    size: deviceObject.fileList[0].fileSize,
    lesson_id: req.body.lessonId,
    duration: 0,
    rsType: "mp4",
  };
  const newResource = await Resource.create(requestData);
  res.status(201).json({
    status: "success",
  });
})

// 删除录播文件夹
exports.deleteDeviceFile = catchAsync(async (req, res, next) => {
  let device = await Device.findOne({
    deviceRoom: req.params.room_id
  })
  if (!device) {
    res.json({
      status: "fail",
      message: "该房间没有设备"
    })
  }
  let room_number = room.room_number
  let newDevice = { deviceIp: device.deviceIP, deviceID: device.deviceID }
  let deviceObject = await new livingDevice(newDevice, room_number)
  await deviceObject.deleteAllFiles();
  res.status(201).json({
    status: "success",
  });
})

